package icasue.base.utils.wareable;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Objects;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @Author: Qiao Hang
 * @CreateDate: 2021/1/25 下午2:38
 * @UpdateDate:
 * @Description:
 */
public class CLog {

    private static OutputStream consoleInfo;
    private static OutputStream consoleError;
    private static ReentrantLock logLock = new ReentrantLock(false);

    static {
        /*try {
            Class<?> self4jConsoleTarget = Class.forName("ch.qos.logback.core.joran.spi.ConsoleTarget");
            Object[] enumConstants = self4jConsoleTarget.getEnumConstants();
            for (Object enumConstant : enumConstants) {
                OutputStream stream = (OutputStream) FieldOF.get_ofTp_fName_instance_.apply(self4jConsoleTarget, "stream", enumConstant);
                if(enumConstant.toString().equals("System.out")) consoleInfo = stream;
                else if(enumConstant.toString().equals("System.err")) consoleError = stream;
            }
        }catch (Throwable e){
            *//*Current logger framework is not self4j. or others not using self4j ignore replace.*//*
            CLog.consoleInfo = new OutputStream() {
                @Override
                public void write(int b) throws IOException { System.out.write(b); }
                @Override
                public void write(byte b[]) throws IOException { System.out.write(b); }
                @Override
                public void write(byte b[], int off, int len) throws IOException { System.out.write(b, off, len); }
                @Override
                public void flush() throws IOException { System.out.flush();}
            };
            CLog.consoleError = new OutputStream() {
                @Override
                public void write(int b) throws IOException { System.err.write(b); }
                @Override
                public void write(byte b[]) throws IOException { System.err.write(b); }
                @Override
                public void write(byte b[], int off, int len) throws IOException { System.err.write(b, off, len); }
                @Override
                public void flush() throws IOException { System.err.flush(); }
            };
        }*/
        //Not using same OutPutStream and not using same lock with logger framework.
        CLog.consoleInfo = new OutputStream() {
            @Override
            public void write(int b) throws IOException { System.out.write(b); }
            @Override
            public void write(byte b[]) throws IOException { System.out.write(b); }
            @Override
            public void write(byte b[], int off, int len) throws IOException { System.out.write(b, off, len); }
            @Override
            public void flush() throws IOException { System.out.flush();}
        };
        CLog.consoleError = new OutputStream() {
            @Override
            public void write(int b) throws IOException { System.err.write(b); }
            @Override
            public void write(byte b[]) throws IOException { System.err.write(b); }
            @Override
            public void write(byte b[], int off, int len) throws IOException { System.err.write(b, off, len); }
            @Override
            public void flush() throws IOException { System.err.flush(); }
        };
    }

    public static void info(String regex,Object... params){
        logLock.lock();
        try {
            if(Objects.nonNull(regex)) {
                consoleInfo.write(String.format(regex + "\n", params).getBytes());
                consoleInfo.flush();
            }
        } catch (Throwable e) { /*Format error. console info ignoring.*/} finally { logLock.unlock(); }
    }

    public static void error(String regex,Object... params){
        logLock.lock();
        try {
            if(Objects.nonNull(regex)) {
                consoleError.write(String.format(regex + "\n", params).getBytes());
                consoleError.flush();
            }
        } catch (Throwable e) { /*Format error. console error ignoring.*/} finally { logLock.unlock(); }
    }
}
